package shopping.dao.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;

import shopping.dao.IBaseDao;
import shopping.entity.ParentEntity;

public abstract class BaseDaoImpl<T extends ParentEntity> extends HibernateDaoSupport implements IBaseDao<T> {
	

	
	//更新
	@Override
    public void update(T entity){
		this.getSessionFactory().getCurrentSession().update(entity);
		//this.getHibernateTemplate().update(entity);
		flush();
	}

	// 插入
	@Override
	public void save(T t) {
		t.setCreateTime(new Date());
		this.getSessionFactory().getCurrentSession().save(t);
		flush();
	}

	// 按id删除
	@Override
	public void deleteById(T clazz) {
		this.getHibernateTemplate().delete(clazz);
		flush();
	}
	
	@Override
	public void findbyHql(String sql,Object... values){
		this.getHibernateTemplate().find(sql, values);
		
	}
	
	@Override
	public List findBySql(String sql,Object... values){
		SQLQuery query = this.getSessionFactory().getCurrentSession().createSQLQuery(sql);  
		
		int i =0;
		for(Object value:values){
			query.setParameter(i, value);
			++i;
		}
		return query.list();
	};

	// 按id查询
	@Override
	public T queryById(Class<T> clazz, int id) {
		@SuppressWarnings("unchecked")
		T t = (T) this.getSessionFactory().getCurrentSession().get(clazz, id);
		return t;
	}
	
    @SuppressWarnings("rawtypes")
    @Override
	public List<T> findByHqlPage(final String hql , final List<Object> values ,final int offset, final int pageSize){
    		List list = getHibernateTemplate().execute(new HibernateCallback<List>() {
			@Override
			public List doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery(hql);
                for(int i=0;i<values.size();i++){
                	query.setParameter(i, values.get(i));
                }
                query.setFirstResult(offset);
                query.setMaxResults(pageSize);
                return query.list();
			}
		});
        return list;
    }
    
    @SuppressWarnings("rawtypes")
    @Override
	public List<T> findByHqlPage(Class<T> classZ ,Map<String,Object> columsAndValues ,final int offset, final int pageSize){
    		List<T> list = getHibernateTemplate().execute(new HibernateCallback<List<T>>() {
			@Override
			public List doInHibernate(Session session) throws HibernateException {
				Criteria citeria = session.createCriteria(classZ);
				if(null != columsAndValues){
					for(String key:columsAndValues.keySet()){
						citeria.add(Restrictions.eq(key, columsAndValues.get(key)));
					}
				}
				citeria.addOrder(Order.desc("id"));
				citeria.setFirstResult(offset);
				citeria.setMaxResults(pageSize);
                return (List)citeria.list();
			}
		});
        return list;
    }
    
	public int countByHql(Class<T> classZ ,Map<String,Object> columsAndValues){
		Integer i  = getHibernateTemplate().execute(new HibernateCallback<Integer>() {
			@Override
			public Integer doInHibernate(Session session) throws HibernateException {
				Criteria citeria = session.createCriteria(classZ);
				if(null != columsAndValues){
					for(String key:columsAndValues.keySet()){
						citeria.add(Restrictions.eq(key, columsAndValues.get(key)));
					}
				}
				citeria.setProjection(Projections.rowCount());
				Object obj = citeria.uniqueResult();
                 return obj == null ? 0 : Integer.valueOf(obj.toString());
			}
		});
		
		return i;
	}
	
    
	//条件查询
    @Override
	public List<T> findByHql(Class<T> classZ ,Map<String,Object> columsAndValues ){
    	List<T> list = getHibernateTemplate().execute(new HibernateCallback<List<T>>() {
			@Override
			public List<T> doInHibernate(Session session) throws HibernateException {
				Criteria citeria = session.createCriteria(classZ);
				if(null != columsAndValues){
					for(String key:columsAndValues.keySet()){
						citeria.add(Restrictions.eq(key, columsAndValues.get(key)));
					}
				}
                return (List)citeria.list();
			}
		});
        return list;
	}
    
    private void flush(){
    	this.getSessionFactory().getCurrentSession().flush();
    }

}
